#include "LinkList2.h"

void testLinkList2() {
    LinkList* ll = (LinkList*)malloc(sizeof(LinkList));
    InitLinkList(ll);
    for (size_t i = 0; i < 10; i++)
        AppendElemet(ll, i);

    TraveseList(ll, showElem);

    puts("Remove:");
    RemoveElement(ll, 0);
    TraveseList(ll, showElem);

    puts("Clear:");
    ClearLinkList(ll);
    TraveseList(ll, showElem);
}

void showElem(ElemType e) {
    printf("%d\n", e);
}

//此处注意：直接传递一个空指针进去，在函数内部进行初始化，将无法成功
void InitLinkList(LinkList* plinklist) {
    if (plinklist) {
        plinklist->head = (pNode)malloc(sizeof(Node));
        plinklist->head->next = NULL;
        plinklist->len = 0;
    }
}

void InsertElement(LinkList* plinklist, int index, ElemType e) {
    if (plinklist) {
        if (index >= 0 && index < plinklist->len) {
            //遍历到插入位置前一个节点
            pNode temp = plinklist->head;
            for (size_t i = 0; i < index; i++)
                temp = temp->next;
            //构造新节点
            pNode newNode = (pNode)malloc(sizeof(Node));
            newNode->data = e;
            newNode->next = temp->next;

            temp->next = newNode;

            plinklist->len++;
        }
        if (index == plinklist->len) {
            //遍历到插入位置前一个节点
            pNode temp = plinklist->head;
            for (size_t i = 0; i < plinklist->len; i++)
                temp = temp->next;
            //构造新节点
            pNode newNode = (pNode)malloc(sizeof(Node));
            newNode->data = e;
            newNode->next = NULL;
            temp->next = newNode;

            plinklist->len++;
        }
    }
}

void AppendElemet(LinkList* plinklist, ElemType e) {
    if (plinklist) {
        InsertElement(plinklist, plinklist->len, e);
    }
}

void RemoveElement(LinkList* plinklist, int index) {
    if (plinklist) {
        if (index >= 0 && index < plinklist->len) {
            pNode temp = plinklist->head;
            for (size_t i = 0; i < index; i++)
                temp = temp->next;
            pNode removedNode = temp->next;
            temp->next = removedNode->next;
            free(removedNode);

            plinklist->len--;
        }
    }
}

void ClearLinkList(LinkList* plinklist) {
    if (plinklist) {
        int len = plinklist->len;
        for (size_t i = 0; i < len; i++)
            RemoveElement(plinklist, 0);
    }
}

void GetElem(LinkList* plinklist, int index, ElemType* pe) {
    if (plinklist) {
        if (index >= 0 && index < plinklist->len) {
            pNode temp = plinklist->head;
            for (size_t i = 0; i < index; i++)
                temp = temp->next;
            temp = temp->next;

            //获得数据
            *pe = temp->data;
        }
    }
}

int GetLength(LinkList* plinklist) {
    return plinklist->len;
}

void TraveseList(LinkList* plinklist, void (*ShowElem)(ElemType e)) {
    if (plinklist) {
        pNode temp = plinklist->head;
        ElemType res;
        for (size_t i = 0; i < plinklist->len; i++) {
            GetElem(plinklist, i, &res);
            (*showElem)(res);
        }
    }
}